package com.sangeng.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sangeng.constants.SystemConstants;
import com.sangeng.domain.ResponseResult;
import com.sangeng.domain.entity.Menu;
import com.sangeng.domain.vo.MenuVo;
import com.sangeng.mapper.MenuMapper;
import com.sangeng.service.MenuService;
import com.sangeng.utils.BeanCopyUtils;
import com.sangeng.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2022-08-19 19:41:13
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Override
    public List<String> selectPermsByUserId(long id) {//根据用户id查询用户的menu所具有的权限
        //权限信息
        List<String> perms;
        //如果是管理员(id == 1) 返回所有的权限
        if (id == 1L) {
            LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
            //菜单
            queryWrapper.in(Menu::getMenuType, SystemConstants.MENU, SystemConstants.BUTTON);
            //未被删除的权限
            queryWrapper.eq(Menu::getStatus, SystemConstants.STATUS_NORMAL);
            List<Menu> menuList = list(queryWrapper);
            //我们需要字符串类型
            perms = menuList.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
        } else {
            //否则，返回对应角色所具有的权限
            //非管理员用户 要先查询用户的角色（连结角色表sys_user_menu里面查询）
            perms = getBaseMapper().selectPermsByUserId(id);//接口泛型是MenuMapper，所以BaseMapper的返回值是一个MenuMapper
        }
        return perms;
    }

    @Override
    public List<MenuVo> selectRouterMenuTreeByUserId(Long userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        List<MenuVo> menuVos = null;
        //判断是否是管理员
        if (SecurityUtils.isAdmin()) {//long类型的数据用equals比较更好
            //如果是 返回所有符合要求的Menu
            menus = menuMapper.selectAllRouterMenu();

        } else {
            //否则 返回当前用户所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }
        System.out.println("==============menus==============");
        System.out.println(menus);
        System.out.println("==============menus==============");
        menuVos = BeanCopyUtils.copyBeanList(menus, MenuVo.class);
        System.out.println("==============menus==============");
        System.out.println(menuVos);
        System.out.println("==============menus==============");
        //构建父子层级的menu
        //构建父子层级菜单
        //先找出第一层的菜单 然后找对应的子菜单设置到children属性中（递归的思路）
        //List<MenuVo> menuTree = builderMenuTree(menuVos, 0L);
        return builderMenuTree(menuVos);
    }

    private List<MenuVo> builderMenuTree(List<MenuVo> menuVos) {
        return menuVos.stream()
                .filter(menuVo -> menuVo.getParentId().equals((long) 0))//parentId = 0
                .map(menuVo -> menuVo.setChildren(getChildren(menuVo, menuVos)))
                .collect(Collectors.toList());
    }

    /**
     * 获取传入参数的子菜单集合
     *
     * @return List<MenuVo>
     */
    private List<MenuVo> getChildren(MenuVo menuVo, List<MenuVo> menuVos) {
        return menuVos.stream()
                .filter(m -> m.getParentId().equals(menuVo.getId()))
                //一般来说两层菜单已经够用了，再加一层会显得前端很繁琐。但是假设子菜单也有子菜单呢？比如系统管理下面有用户管理，用户管理还有呢？递归。
                .map(m -> m.setChildren(getChildren(m, menuVos)))//递归查询子菜单
                .collect(Collectors.toList());
    }


    @Override
    public ResponseResult<List<MenuVo>> getMenuList(String menuName, String status) {
        //查询未被删除的menu 由于设置了自动拼接del_flg查询，所以传入wrapper不用自己填
        //如果有角色名字和状态就要加入条件 “如果”：StringUtils.has
        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(menuName), Menu::getMenuName, menuName);
        wrapper.eq(StringUtils.hasText(status), Menu::getStatus, status);
        //排序 parent_id和order_num
        wrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
        List<Menu> menuList = list(wrapper);
        List<MenuVo> menuVoList = BeanCopyUtils.copyBeanList(menuList, MenuVo.class);
        return ResponseResult.okResult(menuVoList);
    }

    @Override
    public ResponseResult<List<MenuVo>> getAllMenuList() {
        return null;
    }

    @Override
    public ResponseResult<String> addMenu(Menu menuDto) {
        return null;
    }

    @Override
    public ResponseResult<MenuVo> getMenuById(Long id) {
        return null;
    }

    @Override
    public ResponseResult<String> updateMenu(Menu menuDto) {
        return null;
    }

    @Override
    public ResponseResult<String> deleteMenuById(List<Long> idList) {
        return null;
    }
}


